package com.qf.ability.gateway.filter;

import com.qf.ability.gateway.config.AuthParamConfig;
import com.qf.ability.gateway.util.ResponseUtils;
import com.qf.commons.core.utils.JwtUtils;
import com.qf.data.base.r.Codes;
import com.qf.data.base.r.R;
import com.qf.data.base.r.Rs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.List;

@Component
@Slf4j
@RefreshScope
public class AuthFilter implements GlobalFilter {

    @Autowired
    private AuthParamConfig authParamConfig;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("[gateway auth filter] - 用户身份校验的过滤器！");

        //判断请求是否忽略
        URI url = exchange.getRequest().getURI();

        log.info("[gateway auth filter] - 请求的url:{} 忽略的url:{}", url.getPath(), authParamConfig.getIgnore());
        //获取需要忽略的请求地址列表
        List<String> ignore = authParamConfig.getIgnore();
        if (!CollectionUtils.isEmpty(ignore)){
            for (String ignorePath : ignore) {
                if (antPathMatcher.match(ignorePath,url.getPath())){
                    //需要忽略，直接放行
                    return chain.filter(exchange);
                }
            }
        }

        //1、获取请求前端token
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String jwtToken = headers.getFirst("token");

        //判断令牌是否为空
        if (StringUtils.isEmpty(jwtToken)){
            R result = Rs.createFail(Codes.NOT_LOGIN);
            return ResponseUtils.createResponse(result,exchange);
        }

        //令牌不为空，身份解析
        Long uid = JwtUtils.parseJwtToken(jwtToken);
        if (uid == null){
            R result = Rs.createFail(Codes.TOKEN_EXPRES);
            return ResponseUtils.createResponse(result,exchange);
        }

        //身份id不为空，需要传递给后续的微服务，将身份id直接放入请求的请求头/请求参数中
        //创建一个新的请求头
        HttpHeaders newHeader = new HttpHeaders();
        newHeader.putAll(headers);//将原来的请求头数据放入新的请求头
        newHeader.add("uid",uid+"");//将登陆用的用户信息，放入新的请求头中

        //准备一个新的请求
        URI uri = request.getURI();//旧的请求url地址
        ServerHttpRequest newRequest = request.mutate().uri(uri).build();
        newRequest = new ServerHttpRequestDecorator(newRequest){
            @Override
            public HttpHeaders getHeaders() {
                return newHeader;
            }
        };

        //放行
        return chain.filter(exchange.mutate().request(newRequest).build());
    }
}
